package cs3343.project.family;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.HashMap;

/**
 * The Class ConfigManager.
 */
public class ConfigManager {
	
	/** The Constant IMAGE_PATH. */
	public final static String IMAGE_PATH = "res/img/";
	
	/** The Constant IMPORT_PATH. */
	public final static String IMPORT_PATH = "res/import/";
	
	/** The Constant LANG_PATH. */
	public final static String LANG_PATH = "res/lang/";
	
	/** The Constant STAT_PATH. */
	public final static String STAT_PATH = "res/game/";
	
	/** The Constant GAMESTAT_PATH. */
	public final static String GAMESTAT_PATH = STAT_PATH + "statistics/";
	
	/** The Constant ERRORLOG_PATH. */
	public final static String ERRORLOG_PATH = STAT_PATH + "log/";
	
	/** The Constant LANG. */
	public final static String LANG[][] = { { "English", "繁體中文", "簡體中文" }, { "en/", "zh/", "cn/" } };
	
	/** The selected lang path. */
	private static String selectedLangPath = LANG[1][1];
	
	/** The string path. */
	private static String stringPath = LANG_PATH + selectedLangPath + "string.txt";
	
	/** The Constant CONFIG_PATH. */
	public final static String CONFIG_PATH = "res/config/config.ini";
	
	/** The Constant PROFILE_PATH. */
	public final static String PROFILE_PATH = "res/profile/profile.txt";
	
	/** The role path. */
	public static String rolePath = IMPORT_PATH + selectedLangPath + "role.txt";
	
	/** The action card path. */
	public static String actionCardPath = IMPORT_PATH + selectedLangPath + "action.txt"; 
	
	/** The oral card path. */
	public static String oralCardPath = IMPORT_PATH + selectedLangPath + "oral.txt";
	
	/** The tool card path. */
	public static String toolCardPath = IMPORT_PATH + selectedLangPath + "tool.txt"; 
	
	/** The event card path. */
	public static String eventCardPath = IMPORT_PATH + selectedLangPath + "event.txt";
	
	/** The Constant ORALCARD_ZH_PATH. */
	public static final String ORALCARD_ZH_PATH = IMPORT_PATH + "zh/oral.txt";
	
	/** The Constant ORALCARD_EN_PATH. */
	public static final String ORALCARD_EN_PATH = IMPORT_PATH + "en/oral.txt";
	
	/** The Constant ORALCARD_CN_PATH. */
	public static final String ORALCARD_CN_PATH = IMPORT_PATH + "cn/oral.txt";
	
	/** The Constant ACTIONCARD_ZH_PATH. */
	public static final String ACTIONCARD_ZH_PATH = IMPORT_PATH + "zh/action.txt";
	
	/** The Constant ACTIONCARD_EN_PATH. */
	public static final String ACTIONCARD_EN_PATH = IMPORT_PATH + "en/action.txt";
	
	/** The Constant ACTIONCARD_CN_PATH. */
	public static final String ACTIONCARD_CN_PATH = IMPORT_PATH + "cn/action.txt";
	
	/** The Constant GLOBALSTAT_PATH. */
	public final static String GLOBALSTAT_PATH = STAT_PATH + "global.txt";
	
	/** The Constant LASTSTAT_PATH. */
	public final static String LASTSTAT_PATH = STAT_PATH + "last.txt";
	
	/** The Constant MAX_PLAYER. */
	public final static int MAX_PLAYER = 6;
	
	/** The Constant MAX_ROLE. */
	public final static int MAX_ROLE = 6;
	
	/** The Constant DEFAULT_WIN. */
	public final static int DEFAULT_WIN = 1000;
	
	/** The Constant DEFAULT_LOST. */
	public final static int DEFAULT_LOST = 0;
	
	/** The Constant DEFAULT_LANG. */
	public final static int DEFAULT_LANG = 1;
	
	/** The win_esteem. */
	private static int win_esteem = DEFAULT_WIN;
	
	/** The lost_esteem. */
	private static int lost_esteem = DEFAULT_LOST;
	
	/** The lang_index. */
	private static int lang_index = DEFAULT_LANG;
	
	/** The lang strings. */
	private static HashMap<String, String> langStrings = new HashMap<String, String>();
	
	
	/**
	 * Read config.
	 */
	public static void readConfig() {
		String result[];
		try {
	        BufferedReader infile = new BufferedReader(new InputStreamReader(
	        		new FileInputStream(ConfigManager.CONFIG_PATH), "UTF-8"));
	        String str;
	        while ((str = infile.readLine()) != null) 
	        {
	        	if (str.length() > 0) {
                    // UTF - 8 BOM CHAR
                    int c = str.charAt(0);
                    if (c == 65279)
                    	str = str.substring(1, str.length());
	        	}
	            result = str.split(":");

	            if (result[0].equalsIgnoreCase("language")) {
	            	try {
	            		lang_index = Integer.valueOf(result[1]);
	            	}
	            	catch (Exception e) {
	            		System.out.println(e.toString());
	            	}
	            	
	            	switch (lang_index) {
		            	case 0:
		            	case 1:
		            	case 2:
		            		selectedLangPath = LANG[1][lang_index];
		            		break;
		            	default:
		            		selectedLangPath = LANG[1][0];
		            		break;
	            	}
	            	
	            }
	            else if (result[0].equalsIgnoreCase("win")) {
	            	try {
	            		win_esteem = Integer.parseInt(result[1]);	
	            	}
	            	catch (Exception e) {
	        			e.toString();
	        		}	            	
	            }
	            else if (result[0].equalsIgnoreCase("lost")) {
	            	try {
	            		lost_esteem = Integer.parseInt(result[1]);
	            	}
	            	catch (Exception e) {
	        			e.toString();
	        		}
	            }	 
	            else
	            	System.out.println("Error");
	        }
	        setLangPath();
	        infile.close();
	    } 
	    catch (IOException e) {
	    	ConfigManager.saveErrorLog(e.toString());
	    }
	}
	
	/**
	 * Save config.
	 *
	 * @param language the language
	 * @param win the win
	 * @param lost the lost
	 * @return true, if successful
	 */
	public static boolean saveConfig(String language, String win, String lost) {
		try	{
			BufferedWriter outfile = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(ConfigManager.CONFIG_PATH, false), "UTF-8"));
			outfile.append("language:" + language);
			outfile.newLine();
			outfile.append("win:" + win);
			outfile.newLine();
			outfile.append("lost:" + lost);
			outfile.newLine();
			outfile.close();
			return true;
		}
		catch (IOException e) {
			ConfigManager.saveErrorLog(e.toString());
			return false;
		}
	}
	
	/**
	 * Sets the lang path.
	 */
	private static void setLangPath() {
		stringPath = LANG_PATH + selectedLangPath + "string.txt";
		rolePath = IMPORT_PATH + selectedLangPath + "role.txt";
		actionCardPath = IMPORT_PATH + selectedLangPath + "action.txt"; 
		oralCardPath = IMPORT_PATH + selectedLangPath + "oral.txt"; 
		toolCardPath = IMPORT_PATH + selectedLangPath + "tool.txt"; 
		eventCardPath = IMPORT_PATH + selectedLangPath + "event.txt";
	}
	
	/**
	 * Restore default.
	 *
	 * @return true, if successful
	 */
	public static boolean restoreDefault() {
		return saveConfig(String.valueOf(DEFAULT_LANG), String.valueOf(DEFAULT_WIN), String.valueOf(DEFAULT_LOST));
	}
	
	/**
	 * Load lang file.
	 */
	public static void loadLangFile() {
		ConfigManager.readConfig();
		String result[];
		if (!langStrings.isEmpty())
			langStrings.clear();
		try {
	        BufferedReader infile = new BufferedReader(new InputStreamReader(
	        		new FileInputStream(ConfigManager.stringPath), "UTF-8"));
	        String str;
	        while ((str = infile.readLine()) != null) 
	        {
	        	if (str.length() > 0) {
                    // UTF - 8 BOM CHAR
                    int c = str.charAt(0);
                    if (c == 65279)
                    	str = str.substring(1, str.length());
	        	}
	        	
	        	if (!str.startsWith("// ") && !str.isEmpty()) {
	        		result = str.split("=");
	        		langStrings.put(result[0], result[1]);
	        	}
	        }
	        infile.close();
	    } 
	    catch (IOException e) {
	    	ConfigManager.saveErrorLog(e.toString());
	    }
	}

	/**
	 * Gets the selected lang path.
	 *
	 * @return the selected lang path
	 */
	public static String getSelectedLangPath() {
		return selectedLangPath;
	}

	/**
	 * Sets the selected lang path.
	 *
	 * @param selectedLangPath the new selected lang path
	 */
	public static void setSelectedLangPath(String selectedLangPath) {
		ConfigManager.selectedLangPath = selectedLangPath;
	}

	/**
	 * Gets the string path.
	 *
	 * @return the string path
	 */
	public static String getStringPath() {
		return stringPath;
	}

	/**
	 * Sets the string path.
	 *
	 * @param stringPath the new string path
	 */
	public static void setStringPath(String stringPath) {
		ConfigManager.stringPath = stringPath;
	}

	/**
	 * Gets the win_esteem.
	 *
	 * @return the win_esteem
	 */
	public static int getWin_esteem() {
		return win_esteem;
	}

	/**
	 * Sets the win_esteem.
	 *
	 * @param win_esteem the new win_esteem
	 */
	public static void setWin_esteem(int win_esteem) {
		ConfigManager.win_esteem = win_esteem;
	}

	/**
	 * Gets the lost_esteem.
	 *
	 * @return the lost_esteem
	 */
	public static int getLost_esteem() {
		return lost_esteem;
	}

	/**
	 * Sets the lost_esteem.
	 *
	 * @param lost_esteem the new lost_esteem
	 */
	public static void setLost_esteem(int lost_esteem) {
		ConfigManager.lost_esteem = lost_esteem;
	}

	/**
	 * Gets the lang_index.
	 *
	 * @return the lang_index
	 */
	public static int getLang_index() {
		return lang_index;
	}

	/**
	 * Sets the lang_index.
	 *
	 * @param lang_index the new lang_index
	 */
	public static void setLang_index(int lang_index) {
		ConfigManager.lang_index = lang_index;
	}
	
	/**
	 * Gets the lang string.
	 *
	 * @param key the key
	 * @return the lang string
	 */
	public static String getLangString(String key) {
		return langStrings.get(key);
		
	}

	/**
	 * Gets the role path.
	 *
	 * @return the role path
	 */
	public static String getRolePath() {
		return rolePath;
	}

	/**
	 * Sets the role path.
	 *
	 * @param rolePath the new role path
	 */
	public static void setRolePath(String rolePath) {
		ConfigManager.rolePath = rolePath;
	}

	/**
	 * Gets the action card path.
	 *
	 * @return the action card path
	 */
	public static String getActionCardPath() {
		return actionCardPath;
	}

	/**
	 * Sets the action card path.
	 *
	 * @param actionCardPath the new action card path
	 */
	public static void setActionCardPath(String actionCardPath) {
		ConfigManager.actionCardPath = actionCardPath;
	}

	/**
	 * Gets the oral card path.
	 *
	 * @return the oral card path
	 */
	public static String getOralCardPath() {
		return oralCardPath;
	}

	/**
	 * Sets the oral card path.
	 *
	 * @param oralCardPath the new oral card path
	 */
	public static void setOralCardPath(String oralCardPath) {
		ConfigManager.oralCardPath = oralCardPath;
	}

	/**
	 * Gets the tool card path.
	 *
	 * @return the tool card path
	 */
	public static String getToolCardPath() {
		return toolCardPath;
	}

	/**
	 * Sets the tool card path.
	 *
	 * @param toolCardPath the new tool card path
	 */
	public static void setToolCardPath(String toolCardPath) {
		ConfigManager.toolCardPath = toolCardPath;
	}

	/**
	 * Gets the event card path.
	 *
	 * @return the event card path
	 */
	public static String getEventCardPath() {
		return eventCardPath;
	}

	/**
	 * Sets the event card path.
	 *
	 * @param eventCardPath the new event card path
	 */
	public static void setEventCardPath(String eventCardPath) {
		ConfigManager.eventCardPath = eventCardPath;
	}
	
	/**
	 * Generate game statistics folder name.
	 *
	 * @return the string
	 */
	public static String generateGameStatisticsFolderName() {
		Clock c = new Clock();
		String folderPath = ConfigManager.GAMESTAT_PATH + c.toDateTime() + "/";
		createDirectory(folderPath);
		return folderPath;
	}
	
	/**
	 * Creates the directory.
	 *
	 * @param path the path
	 */
	public static void createDirectory(String path) {
		String [] pathAry = path.split("[/]|\\\\");
		StringBuffer list = new StringBuffer();
		for (int i = 0; i < pathAry.length; i++) {
			if (!pathAry[i].equals("")) {
				list.append(pathAry[i] + "/");
				File dir = new File(list.toString());
				if (!dir.isDirectory()) {
					dir.mkdir();
				}
	        }
		}
	}
	
	/**
	 * Save error log.
	 *
	 * @param log the log
	 */
	public static void saveErrorLog(String log) {
		Clock c = new Clock();
		try	{
			BufferedWriter outfile = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(ConfigManager.ERRORLOG_PATH + c.toDate() + ".txt", true), "UTF-8"));
			outfile.newLine();
			outfile.append(c.getCurrentDate() + " " + c.getCurrentTime());
			outfile.newLine();
			outfile.append(log);
			outfile.newLine();
			outfile.close();
		}
		catch (IOException e) {
			System.out.println(e.toString());
		}		
	}
}

